import {
  Button,
  Dropdown,
  Form,
  FormItem,
  Input,
  InputNumber,
  Menu,
  MenuItem,
  Modal,
  RadioGroup,
  Space,
  Spin,
  Switch,
  Textarea,
  Tree
} from 'ant-design-vue'
import { omit, omitBy } from 'lodash-unified'
import { defineComponent, onMounted, ref } from 'vue'

import { dictApi, roleApi } from '@/apis'
import { ProTable } from '@/components'
import { TABLE_FORMAT, TABLE_ITEM_RENDER, TABLE_RENDERER } from '@/constants'
import { TableOptions, useTableRef } from '@/hooks'
import { dictToOptions } from '@/utils'

import { useMenuTree, useOperation, useToolbar } from './hooks'
import styles from './index.module.css'
import { RoleFormType } from './types'

export default defineComponent({
  name: 'RoleView',
  setup() {
    const statusOptions = ref([] as OptionItem[])
    const selectedIds = ref(new Set<string>())
    const tableConfig = ref({
      border: true,
      loading: false,
      toolbarConfig: {
        custom: true,
        refresh: true,
        zoom: true,
        slots: {
          buttons: 'toolbar_buttons'
        }
      },
      formConfig: {
        items: [
          {
            field: 'roleName',
            title: '角色名称',
            itemRender: {
              name: TABLE_ITEM_RENDER.AInput,
              props: {
                placeholder: '请输入角色名称'
              }
            }
          },
          {
            field: 'roleKey',
            title: '权限字符',
            itemRender: {
              name: TABLE_ITEM_RENDER.AInput,
              props: {
                placeholder: '请输入权限字符'
              }
            }
          },
          {
            field: 'status',
            title: '状态',
            itemRender: {
              name: TABLE_ITEM_RENDER.ASelect,
              props: {
                placeholder: '岗位状态'
              }
            }
          },
          {
            field: 'createTime',
            title: '创建时间',
            itemRender: {
              name: TABLE_RENDERER.FormItemDate,
              props: {
                type: 'range',
                placeholder: ['开始时间', '结束时间'],
                valueFormat: 'YYYY-MM-DD',
                keys: ['beginDate', 'endDate']
              }
            }
          },
          {
            itemRender: {
              name: TABLE_RENDERER.FormItemBtns
            }
          }
        ]
      },
      columns: [
        { type: 'checkbox', width: 50 },
        {
          field: 'roleId',
          title: '角色编号'
        },
        {
          field: 'roleName',
          title: '角色名称'
        },
        {
          field: 'roleKey',
          title: '权限字符'
        },
        {
          field: 'roleSort',
          title: '显示顺序'
        },
        {
          field: 'status',
          title: '状态',
          slots: {
            default: 'status'
          }
        },
        {
          field: 'createTime',
          title: '创建时间',
          formatter: TABLE_FORMAT.Date
        },
        {
          title: '操作',
          slots: {
            default: 'operation'
          }
        }
      ],
      pagerConfig: {
        pageSize: 15
      },
      proxyConfig: {
        seq: true,
        form: true,
        props: {
          result: 'list',
          total: 'total'
        },
        ajax: {
          query: async ({ page, form }) => {
            form = processingData(form)

            const data = await roleApi.getRolePage({
              pageSize: page.pageSize,
              pageNum: page.currentPage,
              ...form
            })
            return data
          }
        }
      },
      onCheckboxChange({ checked, row }) {
        checked
          ? selectedIds.value.add(row.roleId)
          : selectedIds.value.delete(row.roleId)
      }
    } as TableOptions)

    const tableRefHook = useTableRef(tableConfig)
    const { checkedKeys, getMenuTree, ...menuTreeRestHook } = useMenuTree()
    const operationHook = useOperation({
      checkedKeys,
      getMenuTree,
      tableRefHook
    })
    const toolbarHook = useToolbar({
      checkedKeys,
      getMenuTree,
      selectedIds,
      tableRefHook
    })

    function processingData(data: any) {
      data = omit(data, ['createTime'])
      data = omitBy(data, value => {
        return value === null
      })

      return data
    }

    async function init() {
      const [dictStatus] = await Promise.all([
        dictApi.getDictDataList('sys_normal_disable')
      ])

      statusOptions.value = dictToOptions(dictStatus)

      tableRefHook.updateFormItem({
        field: 'status',
        key: 'itemRender.props.options',
        value: statusOptions.value
      })
    }

    onMounted(() => {
      init()
    })

    return {
      statusOptions,
      selectedIds,
      tableRef: tableRefHook.tableRef,
      tableConfig,
      checkedKeys,
      ...menuTreeRestHook,
      ...operationHook,
      ...toolbarHook
    }
  },
  render() {
    const renderForm = (type: RoleFormType) => {
      const formModel = type === 'add' ? this.addFormModel : this.editFormModel
      const formRef = type === 'add' ? this.addFormRef : this.editFormRef

      return (
        <Modal
          title={type === 'add' ? '添加角色' : '修改角色'}
          visible={type === 'add' ? this.showAdd : this.showEdit}
          confirmLoading={type === 'add' ? this.addLoading : this.editLoading}
          onOk={type === 'add' ? this.handleAdd : this.handleEdit}
          onCancel={type === 'add' ? this.handleCloseAdd : this.handleCloseEdit}
          destroyOnClose
        >
          <Spin spinning={this.treeLoading}>
            <Form labelCol={{ span: 4 }}>
              <FormItem
                label={'角色名称'}
                {...formRef.validateInfos['roleName']}
              >
                <Input
                  v-model:value={formModel.roleName}
                  placeholder="请输入角色名称"
                />
              </FormItem>
              <FormItem
                label={'权限字符'}
                {...formRef.validateInfos['roleKey']}
              >
                <Input
                  v-model:value={formModel.roleKey}
                  placeholder="请输入权限字符"
                />
              </FormItem>
              <FormItem
                label={'角色顺序'}
                {...formRef.validateInfos['roleSort']}
              >
                <InputNumber v-model:value={formModel.roleSort} />
              </FormItem>
              <FormItem label={'状态'}>
                <RadioGroup
                  v-model:value={formModel.status}
                  options={this.statusOptions}
                ></RadioGroup>
              </FormItem>
              <FormItem label={'菜单权限'}>
                {this.menuTree.length ? (
                  <Tree
                    v-model:checkedKeys={this.checkedKeys}
                    class={styles.treeBorder}
                    treeData={this.menuTree}
                    checkable
                    checkStrictly
                  />
                ) : null}
              </FormItem>
              <FormItem label={'备注'}>
                <Textarea
                  v-model:value={formModel.remark}
                  placeholder="请输入内容"
                />
              </FormItem>
            </Form>
          </Spin>
        </Modal>
      )
    }

    return (
      <div>
        <ProTable
          ref="tableRef"
          v-slots={{
            toolbar_buttons: () => (
              <Space>
                <Button
                  v-permission="system:role:add"
                  type={'primary'}
                  ghost
                  onClick={this.handleShowAdd}
                >
                  新增
                </Button>
                <Button
                  v-permission="system:role:remove"
                  danger
                  ghost
                  disabled={this.selectedIds.size === 0}
                  onClick={this.handleDeleteList}
                >
                  删除
                </Button>
                <Button
                  v-permission="system:role:export"
                  type={'primary'}
                  ghost
                  disabled={!this.canExport}
                  onClick={this.handleExport}
                >
                  导出
                </Button>
              </Space>
            ),
            status: ({ row }) => (
              <Switch
                v-model:checked={row.status}
                checkedValue={'0'}
                unCheckedValue={'1'}
                onChange={() => this.handleToggleStatus(row)}
              ></Switch>
            ),
            operation: ({ row }) =>
              row.roleId !== '1' ? (
                <Space size={'small'}>
                  <Button
                    v-permission="system:role:edit"
                    type={'link'}
                    size={'small'}
                    onClick={() => this.handleShowEdit(row)}
                  >
                    修改
                  </Button>
                  <Button
                    v-permission="system:role:remove"
                    type={'link'}
                    size={'small'}
                    onClick={() => this.handleDelete(row.roleId)}
                  >
                    删除
                  </Button>
                  <Dropdown
                    v-slots={{
                      default: () => (
                        <Button type={'link'} size={'small'}>
                          更多
                        </Button>
                      ),
                      overlay: () => (
                        <Menu>
                          <MenuItem>
                            <Button
                              type={'link'}
                              size={'small'}
                              onClick={() => this.handleAuthUser(row.roleId)}
                            >
                              分配用户
                            </Button>
                          </MenuItem>
                        </Menu>
                      )
                    }}
                  />
                </Space>
              ) : null
          }}
          {...this.tableConfig}
        />
        {/* 添加弹窗 */}
        {renderForm('add')}
        {/* 修改弹窗 */}
        {renderForm('edit')}
      </div>
    )
  }
})
